<!DOCTYPE html>
<html>
<head>
    <title>Waveform Diagram</title>
    <style>
        canvas {
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="650" height="450"></canvas>
    <script>
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');

        // Drawing parameters
        const originX = 100;
        const originY = 250;
        const scale = 8; // pixels per cm

        // Helper function to draw an arrow
        function drawArrow(ctx, fromX, fromY, toX, toY) {
            const headlen = 10; // length of head in pixels
            const dx = toX - fromX;
            const dy = toY - fromY;
            const angle = Math.atan2(dy, dx);
            ctx.moveTo(fromX, fromY);
            ctx.lineTo(toX, toY);
            ctx.lineTo(toX - headlen * Math.cos(angle - Math.PI / 6), toY - headlen * Math.sin(angle - Math.PI / 6));
            ctx.moveTo(toX, toY);
            ctx.lineTo(toX - headlen * Math.cos(angle + Math.PI / 6), toY - headlen * Math.sin(angle + Math.PI / 6));
        }
        
        // Clear canvas
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = "black";
        ctx.strokeStyle = "black";
        ctx.lineWidth = 1.5;
        ctx.font = "16px Arial";

        // Draw Axes
        ctx.beginPath();
        drawArrow(ctx, originX, 400, originX, 50); // y-axis
        drawArrow(ctx, originX - 20, originY, 600, originY); // x-axis
        ctx.stroke();

        // Label Axes
        ctx.fillText("y/cm", originX - 60, 60);
        ctx.fillText("x/cm", 590, originY + 20);
        ctx.fillText("0", originX - 20, originY + 20);

        // Draw Waveform
        // Equation from analysis: y(x) = -10 * cos(PI/3 + (PI/20)*x)
        // or y(x) = 10 * cos( (PI/20)*x - 2*PI/3 )
        ctx.beginPath();
        let firstPoint = true;
        for (let x_cm = -5; x_cm <= 50; x_cm += 0.1) {
            const y_cm = 10 * Math.cos(Math.PI / 20 * x_cm - (2 * Math.PI / 3));
            const canvasX = originX + x_cm * scale;
            const canvasY = originY - y_cm * scale;
            if (firstPoint) {
                ctx.moveTo(canvasX, canvasY);
                firstPoint = false;
            } else {
                ctx.lineTo(canvasX, canvasY);
            }
        }
        ctx.stroke();

        // Add Annotations
        // Ticks and labels on y-axis
        const y_10 = originY - 10 * scale;
        const y_m5 = originY - (-5) * scale;
        ctx.beginPath();
        ctx.moveTo(originX - 5, y_10);
        ctx.lineTo(originX, y_10);
        ctx.moveTo(originX - 5, y_m5);
        ctx.lineTo(originX, y_m5);
        ctx.stroke();
        ctx.fillText("10", originX - 35, y_10 + 5);
        ctx.fillText("-5", originX - 35, y_m5 + 5);

        // Dashed line for amplitude
        const x_peak = 40 / 3; // x where wave is at peak y=10
        const canvasX_peak = originX + x_peak * scale;
        ctx.beginPath();
        ctx.setLineDash([4, 4]);
        ctx.moveTo(originX, y_10);
        ctx.lineTo(canvasX_peak, y_10);
        ctx.stroke();
        ctx.setLineDash([]);

        // Points P and Q
        const x_p = 10 / 3; // Node P
        const x_q = 70 / 3; // Node Q
        const canvasX_p = originX + x_p * scale;
        const canvasX_q = originX + x_q * scale;
        ctx.font = "italic 20px Times New Roman";
        ctx.fillText("P", canvasX_p - 5, originY + 25);
        ctx.fillText("Q", canvasX_q - 5, originY + 25);
        
        // Dimension line for 20cm
        ctx.font = "16px Arial";
        const dim_y = originY + 50;
        const tick_h = 10;
        ctx.beginPath();
        // Vertical ticks
        ctx.moveTo(canvasX_p, originY);
        ctx.lineTo(canvasX_p, dim_y + tick_h);
        ctx.moveTo(canvasX_q, originY);
        ctx.lineTo(canvasX_q, dim_y + tick_h);
        // Horizontal line with arrows
        const mid_x = (canvasX_p + canvasX_q) / 2;
        const textWidth = ctx.measureText("20").width;
        const gap = textWidth / 2 + 5;
        ctx.moveTo(mid_x - gap, dim_y);
        ctx.lineTo(canvasX_p, dim_y);
        drawArrow(ctx, mid_x - gap, dim_y, canvasX_p, dim_y);

        ctx.moveTo(mid_x + gap, dim_y);
        ctx.lineTo(canvasX_q, dim_y);
        drawArrow(ctx, mid_x + gap, dim_y, canvasX_q, dim_y);
        ctx.stroke();
        ctx.fillText("20", mid_x - textWidth / 2, dim_y - 5);


        // Propagation direction arrow 'u'
        ctx.beginPath();
        ctx.lineWidth = 2;
        const arrow_y = originY - 120;
        drawArrow(ctx, originX + 28 * scale, arrow_y, originX + 18 * scale, arrow_y);
        ctx.stroke();
        ctx.font = "italic bold 20px Times New Roman";
        ctx.fillText("u", originX + 22 * scale, arrow_y - 15);

        // Caption
        ctx.font = "20px 'KaiTi', 'SimSun'";
        ctx.fillStyle = "black";
        ctx.fillText("习题 11-9 图", canvas.width / 2 - 60, canvas.height - 20);

    </script>
</body>
</html>